package com.telecom.restaurant.service;

import com.alibaba.fastjson.JSON;
import com.telecom.restaurant.constant.*;
import com.telecom.restaurant.dao.*;
import com.telecom.restaurant.domin.PaginationResult;
import com.telecom.restaurant.domin.vo.CartFoodVO;
import com.telecom.restaurant.domin.vo.OrderConfirmVO;
import com.telecom.restaurant.domin.vo.OrderFoodVO;
import com.telecom.restaurant.domin.vo.OrderVO;
import com.telecom.restaurant.enums.FoodTypeEnum;
import com.telecom.restaurant.enums.OrderStatusEnum;
import com.telecom.restaurant.enums.OrderTypeEnum;
import com.telecom.restaurant.exception.BizException;
import com.telecom.restaurant.model.*;
import com.telecom.restaurant.model.param.OrderSearchParam;
import com.telecom.restaurant.util.DateUtil;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.poi.hssf.usermodel.*;
import org.apache.poi.ss.usermodel.HorizontalAlignment;
import org.apache.poi.ss.usermodel.VerticalAlignment;
import org.apache.poi.ss.util.CellRangeAddress;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.OutputStream;
import java.util.*;

/**
 * Created by qiqi on 2019/12/15.
 */
@Service
@EnableScheduling
public class OrderService {
    private Logger logger = LoggerFactory.getLogger(getClass());

    @Autowired
    private OrderDao orderDao;

    @Autowired
    private UserCartDao userCartDao;

    @Autowired
    private MenuDayToFoodDao menuDayToFoodDao;

    @Autowired
    private MenuDayDao menuDayDao;

    @Autowired
    private CouponCustomerDao couponCustomerDao;

    @Autowired
    private CustomerCouponUseDao customerCouponUseDao;

    @Autowired
    private FoodService foodService;

    @Autowired
    private CartService cartService;

    @Autowired
    private PictureService pictureService;

    Random random = new Random(System.currentTimeMillis());

    private List<OrderPO> searchOrder(OrderSearchParam param) {
        List<OrderPO> orderList = orderDao.searchOrder(param);
        return orderList;
    }

    public PaginationResult searchOrderForShow(OrderSearchParam param) {

        PaginationResult result = new PaginationResult(param);

        int count = orderDao.count(param);
        result.setCount(count);
        if (count > 0) {
            List<OrderPO> orderList = orderDao.searchOrder(param);
            List<OrderVO> voList = this.constructOrderVO(orderList);
            result.setDataList(voList);
        }

        return result;
    }

    public OrderVO getOrderVOById(Long id) {

        OrderPO orderPO = orderDao.selectByPrimaryKey(id);
        if (orderPO == null) {
            return null;
        }
        OrderVO vo = this.convertPO2VO(orderPO);
        return vo;
    }


    /**
     * 取消订单
     *
     * @param orderStatus
     * @return
     */
    @Transactional
    public boolean cancelOrder(Long orderId, OrderStatusEnum orderStatus) throws BizException {

        OrderPO orderPO = orderDao.getCancelOrderInfo(orderId);
        if (orderPO == null) {
            throw new BizException(DataResultConstant.ORDER_ID_NOT_EXIST);
        }
        if (orderPO.getStatus() != OrderStatusEnum.WAIT_PAY.getCode()) {
            throw new BizException(DataResultConstant.ORDER_STATUS_CANT_CANCEL);
        }

        // 判断下单时间  如果是下单时间，那么回退库存
        if (returnDayIfCanOrder() >= 0 && StringUtils.isNotBlank(orderPO.getCartSnapshot())) {
            List<UserCartPO> userCartPOList = JSON.parseArray(orderPO.getCartSnapshot(), UserCartPO.class);
            if (CollectionUtils.isNotEmpty(userCartPOList)) {
                // 回归库存
                List<Long> menuFoodIsList = new ArrayList<>();
                for (UserCartPO userCartPO : userCartPOList) {
                    String[] menuFoodIdArray = userCartPO.getMenuFoodIds().split(",");
                    for (String menuFoodIdString : menuFoodIdArray) {
                        menuFoodIsList.add(Long.valueOf(menuFoodIdString));
                    }
                    // 逐个菜品回滚库存
                    List<MenuDayToFoodPO> menuDayToFoodPOList = menuDayToFoodDao.selectByIds(menuFoodIsList);
                    for (MenuDayToFoodPO menuDayToFoodPO : menuDayToFoodPOList) {
                        menuDayToFoodDao.changeStock(menuDayToFoodPO.getId(), userCartPO.getCount());
                    }
                    menuFoodIsList.clear();
                }

            }
        }
        // 判断是否使用了优惠券
        if (orderPO.getCouponMoney() != null && orderPO.getCouponMoney() > 0) {
            // 使用了优惠券  回退
            customerCouponUseDao.updateUnused(orderPO.getCustomerId(), orderId);
        }

        // 更新订单状态
        int result = orderDao.updateOrderStatus(orderId, orderStatus.getCode(), OrderStatusEnum.WAIT_PAY.getCode());
        if (result < 1) {
            throw new BizException(DataResultConstant.ORDER_STATUS_CANT_CANCEL);
        }
        return true;
    }

    /**
     * 取餐
     *
     * @param param
     * @return
     */
    public List<OrderVO> pickOrder(OrderSearchParam param) {
        param.setWithFoodInfo(true);
        List<OrderPO> orderList = searchOrder(param);

        if (orderList == null || orderList.isEmpty()) {
            return Collections.emptyList();
        }

        List<Long> pickOrderList = new ArrayList<>();

        for (OrderPO orderPO : orderList) {
            // 取餐
            pickOrderList.add(orderPO.getId());
            orderPO.setStatus(OrderStatusEnum.FINISH.getCode());
            orderPO.setActualPickTime(new Date());
        }

        if (CollectionUtils.isNotEmpty(pickOrderList)) {
            orderDao.batchPickFood(pickOrderList, OrderStatusEnum.FINISH.getCode());
            List<OrderVO> voList = this.constructOrderVO(orderList);
            return voList;
        }
        return Collections.emptyList();
    }

    public List<OrderVO> constructOrderVO(List<OrderPO> orderPOList) {
        if (orderPOList == null || orderPOList.isEmpty()) {
            return Collections.emptyList();
        }
        List<OrderVO> voList = new ArrayList<>(orderPOList.size());
        for (OrderPO po : orderPOList) {
            OrderVO vo = this.convertPO2VO(po);
            voList.add(vo);
        }
        return voList;
    }

    /**
     * 判断当前时间是否可以下单
     *
     * @return
     */
    public int returnDayIfCanOrder() {

        Calendar cal = Calendar.getInstance();
        cal.setFirstDayOfWeek(Calendar.MONDAY);
        cal.setTimeInMillis(System.currentTimeMillis());
        int dayWeek = cal.get(Calendar.DAY_OF_WEEK);// 获得当前日期是一个星期的第几天
        if (dayWeek < 2 || dayWeek > 6) {
            return -1;
        }
        int hour = cal.get(Calendar.HOUR_OF_DAY);
        if (hour > DefaultConstant.CAN_ORDER_HOUR) {
            return -1;
        } else if (hour == DefaultConstant.CAN_ORDER_HOUR) {
            int minute = cal.get(Calendar.MINUTE);
            if (minute > DefaultConstant.CAN_ORDER_MINUTE) {
                return -1;
            }
        }
        return dayWeek - 2;
    }

    public List<UserCartPO> checkCart(Long userId, boolean minusStock) throws BizException {

        List<UserCartPO> userCartPOList = userCartDao.selectByUserId(userId);

        if (userCartPOList == null || userCartPOList.isEmpty()) {
            throw new BizException(DataResultConstant.CART_IS_EMPTY);
        }

        // 1.检查下单菜单
        List<Long> menuFoodIsList = new ArrayList<>();
        Long menuDayId = null;
        for (UserCartPO userCartPO : userCartPOList) {
            String[] menuFoodIdArray = userCartPO.getMenuFoodIds().split(",");
            for (String menuFoodIdString : menuFoodIdArray) {
                menuFoodIsList.add(Long.valueOf(menuFoodIdString));
            }
            // 检查购物车的菜品 是否都是对应类型
            // 查询关联菜单
            List<MenuDayToFoodPO> menuDayToFoodPOList = menuDayToFoodDao.selectByIds(menuFoodIsList);
            int packageDishCount = 0;
            int packageMainCount = 0;
            for (MenuDayToFoodPO menuDayToFoodPO : menuDayToFoodPOList) {
                // 主食固定id小于0，此处进行特殊处理
                if (menuDayToFoodPO.getId() >= 0) {
                    if (menuDayId == null) {
                        menuDayId = menuDayToFoodPO.getMenuDayId();
                    } else {
                        if (!menuDayId.equals(menuDayToFoodPO.getMenuDayId())) {
                            // 选择的菜品不是同一天的
                            throw new BizException(DataResultConstant.CHOOSE_FOOD_WRONG);
                        }
                    }
                    if (menuDayToFoodPO.getCount() < userCartPO.getCount()) {
                        throw new BizException(DataResultConstant.FOOD_STOCK_NOT_ENOUGH);
                    }
                    if (minusStock) {
                        // minus stock
                        int minusStockResult = menuDayToFoodDao.changeStock(menuDayToFoodPO.getId(), -userCartPO.getCount());
                        if (minusStockResult < 1) {
                            throw new BizException(DataResultConstant.FOOD_STOCK_NOT_ENOUGH);
                        }
                    }
                }

                Long foodId = menuDayToFoodPO.getFoodId();
                FoodPO food = foodService.getFoodById(foodId);
                if (food == null) {
                    // 选择的菜品不是同一天的
                    logger.error("Can't get food. foodId:{}, userCart:{}, menuFood:{}", foodId,
                            JSON.toJSONString(userCartPO), JSON.toJSONString(menuDayToFoodPO));
                    throw new BizException(DataResultConstant.DATA_ERROR);
                }
                if (userCartPO.getType() == FoodTypeEnum.ORDER_OTHER_FOOD.getCode()) {
                    // 单点
                    if (food.getType() != FoodTypeEnum.OTHER_MAIN.getCode() &&
                            food.getType() != FoodTypeEnum.OTHER_DISH.getCode()) {

                        logger.error("Wrong food type. food:{}, userCart:{}, menuFood:{}",
                                JSON.toJSONString(food),
                                JSON.toJSONString(userCartPO),
                                JSON.toJSONString(menuDayToFoodPO));
                        throw new BizException(DataResultConstant.DISH_TYPE_WRONG);
                    }
                } else {
                    // 套餐
                    if (food.getType() == FoodTypeEnum.PACKAGE_DISH.getCode()) {
                        packageDishCount++;
                    } else if (food.getType() == FoodTypeEnum.PACKAGE_MAIN.getCode()) {
                        packageMainCount++;
                    } else {
                        logger.error("Wrong food type. food:{}, userCart:{}, menuFood:{}",
                                JSON.toJSONString(food),
                                JSON.toJSONString(userCartPO),
                                JSON.toJSONString(menuDayToFoodPO));
                        throw new BizException(DataResultConstant.DISH_TYPE_WRONG);
                    }
                }
            }
            if (userCartPO.getType() == FoodTypeEnum.ORDER_PACKAGE_FOOD.getCode()) {
                if (packageDishCount != 4 && packageMainCount != 1) {
                    logger.error("Wrong food count. userCart:{}", JSON.toJSONString(userCartPO));
                    throw new BizException(DataResultConstant.PACKAGE_FOOD_COUNT_ERROR);
                }
            }
            menuFoodIsList.clear();
        }

        // 检查当天菜单
        MenuDayPO menuDayPO = menuDayDao.selectByPrimaryKey(menuDayId);
        // 菜单数据错误
        if (menuDayPO == null) {
            throw new BizException(DataResultConstant.WRONG_MENU_DATA);
        }
        // 非晚餐
//        if (menuDayPO.getType() != MenuTypeEnum.DINNER.getCode()) {
//            throw new BizException(DataResultConstant.DINNER_ONLY);
//        }

        // 如果扣库存，说明在下单，将restaurantId保存下，后面使用
        if (minusStock == true) {
            ManageThreadLocal.restaurantId.set(menuDayPO.getRestaurantId());
        }


        return userCartPOList;
    }

    /**
     * 预下单。跳转订单确认页
     *
     * @param userId
     * @return
     * @throws BizException
     */
    public List<OrderConfirmVO> preOrder(Long userId) throws BizException {

        List<UserCartPO> foodPOList = checkCart(userId, false);
        if (CollectionUtils.isEmpty(foodPOList)) {
            throw new BizException(DataResultConstant.CART_IS_EMPTY);
        }

        List<OrderConfirmVO> resultVo = new ArrayList<>(2);

        // 2020-1-1 添加  下单需要分开，不同的订单，不同的支付商户
        // 只有套餐可以使用优惠券
        List<UserCartPO> packageOrderFoodList = new ArrayList<>(); // 套餐
        List<UserCartPO> otherOrderFoodList = new ArrayList<>(); // 小吃
        for (UserCartPO userCartPO : foodPOList) {
            if (userCartPO.getType() == FoodTypeEnum.ORDER_PACKAGE_FOOD.getCode()) {
                packageOrderFoodList.add(userCartPO);
            } else {
                otherOrderFoodList.add(userCartPO);
            }
        }
        Date orderDate = new Date();
        if (CollectionUtils.isNotEmpty(packageOrderFoodList)) {
            // 处理套餐
            OrderConfirmVO packageOrderVO = new OrderConfirmVO();
            List<CartFoodVO> foodVoList = cartService.convertVOList(packageOrderFoodList);
            packageOrderVO.setDishList(foodVoList);

            int total = 0;
            for (UserCartPO userCartPO : packageOrderFoodList) {
                total += (userCartPO.getCount() * userCartPO.getPrice());
            }
            packageOrderVO.setOriginPrice(total);
            if (total > DefaultConstant.COUPON_AMOUNT && hasCouponCanUse(userId, orderDate)) {
                packageOrderVO.setCoupon(DefaultConstant.COUPON_AMOUNT);
            } else {
                packageOrderVO.setCoupon(0);
            }
            packageOrderVO.setNeedPay(total - packageOrderVO.getCoupon());
            packageOrderVO.setType(OrderTypeEnum.PACKAGE.getCode());
            resultVo.add(packageOrderVO);
        }
        if (CollectionUtils.isNotEmpty(otherOrderFoodList)) {
            // 处理小吃
            OrderConfirmVO otherDishOrder = new OrderConfirmVO();

            List<CartFoodVO> foodVoList = cartService.convertVOList(otherOrderFoodList);
            otherDishOrder.setDishList(foodVoList);

            int total = 0;
            for (UserCartPO userCartPO : otherOrderFoodList) {
                total += (userCartPO.getCount() * userCartPO.getPrice());
            }
            otherDishOrder.setCoupon(0);
            otherDishOrder.setOriginPrice(total);
            otherDishOrder.setNeedPay(total);
            otherDishOrder.setType(OrderTypeEnum.OTHER.getCode());
            resultVo.add(otherDishOrder);
        }

        return resultVo;
    }

    /**
     * 提交订单，需要是事务
     *
     * @param useCoupon
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    public List<OrderVO> confirmOrder(Long userId, boolean useCoupon) throws BizException {

        String mobile = UserThreadLocal.mobile.get();
        // 检查购物车，并且扣库存
        List<UserCartPO> foodPOList = checkCart(userId, true);
        if (CollectionUtils.isEmpty(foodPOList)) {
            throw new BizException(DataResultConstant.CART_IS_EMPTY);
        }

        // 2020-1-1 添加  下单需要分开，不同的订单，不同的支付商户
        // 只有套餐可以使用优惠券
        List<UserCartPO> packageOrderFoodList = new ArrayList<>(); // 套餐
        List<UserCartPO> otherOrderFoodList = new ArrayList<>(); // 小吃
        for (UserCartPO userCartPO : foodPOList) {
            if (userCartPO.getType() == FoodTypeEnum.ORDER_PACKAGE_FOOD.getCode()) {
                packageOrderFoodList.add(userCartPO);
            } else {
                otherOrderFoodList.add(userCartPO);
            }
        }
        Date orderDate = new Date();
        OrderPO packageOrder = null;
        OrderPO otherDishOrder = null;
        int dayNo = 0;
        if (CollectionUtils.isNotEmpty(packageOrderFoodList)) {
            // 处理套餐订单
            // 如果使用优惠券，检查优惠券，并且插入记录
            CustomerCouponUsePO customerCouponUsePO = null;
            if (useCoupon) {
                if (!hasCouponCanUse(userId, orderDate)) {
                    throw new BizException(DataResultConstant.COUPON_USED);
                }
                customerCouponUsePO = useCoupon(userId, orderDate);
            }
            packageOrder = createOrder(packageOrderFoodList, orderDate, userId, mobile, OrderTypeEnum.PACKAGE, useCoupon);
            // 如果支付金额为0，自动已支付
            if (packageOrder.getPayMoney() == 0) {
                packageOrder.setStatus(OrderStatusEnum.WAIT_PICK.getCode());
            }
            // 订单写入
            orderDao.insert(packageOrder);

            // 修改dayNo
            dayNo = setOrderDayNoAndPickCode(packageOrder, dayNo);

            // 订单号回写优惠券
            if (customerCouponUsePO != null) {
                customerCouponUsePO.setOrderId(packageOrder.getId());
                customerCouponUseDao.updateOrderId(customerCouponUsePO);
            }
        }
        if (CollectionUtils.isNotEmpty(otherOrderFoodList)) {
            // 处理小吃订单
            otherDishOrder = createOrder(otherOrderFoodList, orderDate, userId, mobile, OrderTypeEnum.OTHER, false);
            // 如果支付金额为0，自动已支付
            if (otherDishOrder.getPayMoney() == 0) {
                otherDishOrder.setStatus(OrderStatusEnum.WAIT_PICK.getCode());
            }

            // 订单写入
            orderDao.insert(otherDishOrder);

            // 修改dayNo
            setOrderDayNoAndPickCode(otherDishOrder, dayNo);
        }

        // 清空购物车
        cartService.clearCart(userId);

        List<OrderVO> orderVOList = new ArrayList<>(2);
        if (packageOrder != null) {
            OrderVO orderVO = this.convertPO2VO(packageOrder);
            orderVOList.add(orderVO);
        }
        if (otherDishOrder != null) {
            OrderVO orderVO = this.convertPO2VO(otherDishOrder);
            orderVOList.add(orderVO);
        }

        return orderVOList;
    }

    private OrderPO createOrder(List<UserCartPO> foodList, Date orderDate, Long userId, String Mobile, OrderTypeEnum orderType, boolean useCoupon) {

        int total = 0;
        int couponAmount = 0;
        if (useCoupon) {
            couponAmount = DefaultConstant.COUPON_AMOUNT;
        }
        for (UserCartPO userCartPO : foodList) {
            total += (userCartPO.getCount() * userCartPO.getPrice());
        }

        // 构造订单
        OrderPO orderPO = new OrderPO();
        Long restaurantId = ManageThreadLocal.restaurantId.get();
        orderPO.setRestaurantId(restaurantId);
        orderPO.setCustomerId(userId);
        orderPO.setCustomerMobile(Mobile);
        orderPO.setDayNo(1);
        orderPO.setType(orderType.getCode());
        orderPO.setOrderTime(orderDate);
        orderPO.setPickDate(orderDate);
        orderPO.setOriginMoney(total);
        orderPO.setCouponMoney(couponAmount);
        orderPO.setPayMoney(total - couponAmount);
        orderPO.setStatus(OrderStatusEnum.WAIT_PAY.getCode());

        // 菜品快照
        List<CartFoodVO> cartFoodVOList = cartService.convertVOList(foodList);
        List<OrderFoodVO> foodVoList = new ArrayList<>(cartFoodVOList.size());
        for (CartFoodVO cartFoodVO : cartFoodVOList) {
            foodVoList.add(cartFoodVO);
        }
        orderPO.setFoodSnapshot(JSON.toJSONString(foodVoList));
        orderPO.setCartSnapshot(JSON.toJSONString(foodList));

        // 20200223 特殊需求 订餐
        if (orderPO.getPayMoney() == 0 && cartFoodVOList.size() == 1) {
            orderPO.setType(OrderTypeEnum.BOOK.getCode());
        }

        return orderPO;
    }

    /**
     * 检查是否有优惠券
     *
     * @param userId
     * @return
     */
    public boolean hasCouponCanUse(Long userId, Date orderDate) {

        String mobile = UserThreadLocal.mobile.get();
        //检查优惠券
        CouponCustomerPO coupon = couponCustomerDao.searchByMobile(mobile);
        if (coupon != null && coupon.getStatus() == 1) {
            // 有优惠券可以用
            boolean result = true;
            List<CustomerCouponUsePO> couponUseList = customerCouponUseDao.getByCustomerAndDate(userId, orderDate);
            for (CustomerCouponUsePO customerCouponUsePO : couponUseList) {
                if (customerCouponUsePO.getUsed() == 1) {
                    result = false;
                }
            }
            return result;
        }
        return false;
    }

    /**
     * 订单支付
     *
     * @param orderId
     * @return
     */
    public boolean payOrder(Long orderId) {
        int result = orderDao.updateOrderStatus(orderId, OrderStatusEnum.WAIT_PICK.getCode(), OrderStatusEnum.WAIT_PAY.getCode());
        return result == 1;
    }

    public CustomerCouponUsePO useCoupon(Long userId, Date orderDate) throws BizException {

        CustomerCouponUsePO customerCouponUsePO = new CustomerCouponUsePO();
        customerCouponUsePO.setUsed(1);
        customerCouponUsePO.setCustomerId(userId);
        customerCouponUsePO.setDate(orderDate);

        customerCouponUseDao.insert(customerCouponUsePO);
        // count
        int usedCount = customerCouponUseDao.countUsed(userId, orderDate);
        if (usedCount > 1) {
            throw new BizException(DataResultConstant.COUPON_USED);
        }
        return customerCouponUsePO;
    }

    public int setOrderDayNoAndPickCode(OrderPO orderPO, int dayNo) {

        int count = dayNo;

        if (dayNo <= 0) {
            OrderSearchParam param = new OrderSearchParam();
            param.setLessThanId(orderPO.getId());
            param.setRestaurantId(orderPO.getRestaurantId());
            param.setOrderDate(orderPO.getOrderTime());
            count = orderDao.count(param);
        }

        OrderPO newOrderPO = new OrderPO();
        newOrderPO.setId(orderPO.getId());
        newOrderPO.setDayNo(count);
        newOrderPO.setPickCode(String.valueOf(count));
        orderDao.updateByPrimaryKeySelective(newOrderPO);
        orderPO.setDayNo(count);
        orderPO.setPickCode(newOrderPO.getPickCode());
        return count;
    }

    public OrderVO convertPO2VO(OrderPO po) {
        OrderVO vo = new OrderVO();
        vo.setOrderId(po.getId());
        vo.setDayNo(po.getDayNo());
        vo.setMobile(po.getCustomerMobile());
        vo.setOrderTime(DateUtil.convertDate2TimeString(po.getOrderTime()));
        vo.setActualPickTime(DateUtil.convertDate2TimeString(po.getActualPickTime()));
        vo.setPickCode(po.getPickCode());
        vo.setType(po.getType());
        vo.setStatus(po.getStatus());
        vo.setOriginPrice(po.getOriginMoney());
        vo.setCouponPrice(po.getCouponMoney());
        vo.setTotalPrice(po.getPayMoney());
        if (po.getPayTime() != null) {
            vo.setPayTime(DateUtil.convertDate2TimeString(po.getPayTime()));
        }
        if (StringUtils.isNotBlank(po.getFoodSnapshot())) {
            List<OrderFoodVO> foodVOList = com.alibaba.fastjson.JSON.parseArray(po.getFoodSnapshot(), OrderFoodVO.class);
            pictureService.renderOrderFoodVOListPicture(foodVOList);
            vo.setFoodList(foodVOList);
        }
        return vo;
    }


    /**
     * 导出当天的订单
     *
     * @param restaurantId
     * @param orderDate
     * @param out
     * @throws Exception
     */
    public void exportTodayOrderList(Long restaurantId, Date orderDate, OutputStream out) throws Exception {
        try {
            // 第一步，创建一个workbook，对应一个Excel文件
            HSSFWorkbook workbook = new HSSFWorkbook();

            // 第二步，在webbook中添加一个sheet,对应Excel文件中的sheet
            HSSFSheet hssfSheet = workbook.createSheet("sheet1");

            // 第三步，在sheet中添加表头第0行,注意老版本poi对Excel的行数列数有限制short
            HSSFRow row = hssfSheet.createRow(0);

            // 第四步，创建单元格，并设置值表头 设置表头居中
            HSSFCellStyle titleStyle = workbook.createCellStyle();
            titleStyle.setAlignment(HorizontalAlignment.CENTER);//水平居中

            HSSFCellStyle dataStyle = workbook.createCellStyle();
            dataStyle.setVerticalAlignment(VerticalAlignment.CENTER);//垂直居中
            dataStyle.setAlignment(HorizontalAlignment.CENTER);//水平居中

            HSSFCell hssfCell = null;
            for (int i = 0; i < ExportExcelConstant.ORDER_LIST_TITLE.length; i++) {
                hssfCell = row.createCell(i);//列索引从0开始
                hssfCell.setCellStyle(titleStyle);
                hssfCell.setCellValue(ExportExcelConstant.ORDER_LIST_TITLE[i]);//列名1
            }

            // 第五步，写入数据
            // 查询订单
            OrderSearchParam param = new OrderSearchParam();
            param.setRestaurantId(restaurantId);
            param.setOrderDate(orderDate);
            param.setStatus(OrderStatusEnum.WAIT_PICK.getCode());
            param.setWithFoodInfo(true);

            int pageNo = 1;
            int rowIndex = 1;
            while (true) {
                param.setPageNo(pageNo++);
                List<OrderPO> orderPOList = orderDao.searchOrder(param);
                if (orderPOList == null || orderPOList.isEmpty()) {
                    break;
                }
                for (OrderPO orderPO : orderPOList) {
                    rowIndex = this.writeFoodListToExcel(hssfSheet, dataStyle, rowIndex, orderPO);
                }

                if (orderPOList.size() < param.getPageSize()) {
                    break;
                }
            }

            // 第七步，将文件输出到客户端浏览器
            try {
                workbook.write(out);
                out.flush();
                out.close();

            } catch (Exception e) {
                logger.error("exprt file error. restaurantId:{}", restaurantId, e);
            }
        } catch (Exception e) {
            logger.error("exprt file error. restaurantId:{}", restaurantId, e);
            throw new Exception("导出信息失败！");

        }
    }

    private int writeFoodListToExcel(HSSFSheet hssfSheet, HSSFCellStyle style, int rowIndex, OrderPO orderPO) {
        if (orderPO == null) {
            return rowIndex;
        }
        int beginIndex = rowIndex;

        List<OrderFoodVO> foodVOList = com.alibaba.fastjson.JSON.parseArray(orderPO.getFoodSnapshot(), OrderFoodVO.class);
        for (OrderFoodVO foodVO : foodVOList) {
            // "序号/取餐码", "类型", "菜品", "数量", "手机号
            HSSFRow row = hssfSheet.createRow(rowIndex);
            if (beginIndex == rowIndex) {
                this.setCell(row, 0, String.valueOf(orderPO.getDayNo()), style);
                this.setCell(row, 4, orderPO.getCustomerMobile(), style);
                hssfSheet.setColumnWidth(4, 3200);
            }

            if (foodVO.getType() == FoodTypeEnum.ORDER_PACKAGE_FOOD.getCode()) {
                this.setCell(row, 1, FoodTypeEnum.ORDER_PACKAGE_FOOD.getDesc(), style);
            } else {
                this.setCell(row, 1, FoodTypeEnum.ORDER_OTHER_FOOD.getDesc(), style);
            }

            HSSFCell foodNameCell = this.setCell(row, 2, foodVO.getName(), style);
            int colLength = foodNameCell.getStringCellValue().getBytes().length * 256;  //
            hssfSheet.setColumnWidth(2, colLength);

            this.setCell(row, 3, String.valueOf(foodVO.getCount()), style);
            rowIndex++;
        }
        // 需要合并单元格
        if (rowIndex - beginIndex > 1) {
            // 合并取餐码
            CellRangeAddress region1 = new CellRangeAddress(beginIndex, rowIndex - 1, 0, 0);
            hssfSheet.addMergedRegion(region1);
            hssfSheet.getRow(beginIndex).getCell(0).setCellStyle(style);

            // 合并手机号
            CellRangeAddress region2 = new CellRangeAddress(beginIndex, rowIndex - 1, 4, 4);
            hssfSheet.addMergedRegion(region2);
            hssfSheet.getRow(beginIndex).getCell(4).setCellStyle(style);
        }

        return rowIndex;
    }

    private HSSFCell setCell(HSSFRow row, int index, String value, HSSFCellStyle style) {
        HSSFCell hssfCell = row.createCell(index);
        hssfCell.setCellStyle(style);
        hssfCell.setCellValue(value);
        return hssfCell;
    }


}
